home *** CD-ROM | disk | FTP | other *** search
/ FishMarket 1.0 / FishMarket v1.0.iso / fishies / 101-125 / disk_111 / assigndev / simplestartup.c < prev   
C/C++ Source or Header  |  1992-05-06  |  8KB  |  308 lines

  1. #undef  WB_PARSE        /* Look at the WINDOW tooltype */
  2. #undef  WB_OPEN_NIL        /* Just open NIL: for io if started from Workbench */
  3. #undef  WB_CLOSE_FILES    /* This should normally be set if one of the other */
  4.                         /* WB_ flags is */
  5. #define  CLI_PARSE         /* Do CLI argument parsing */
  6.  
  7. /*
  8.  *    This is a simplified startup module for Manx. The only extra module
  9.  *    that is linked is crt0.
  10.  *
  11.  *    This module does NOT support each of the following:
  12.  *    . stdin, stdout, stderr. Use Input() and Output() instead. Don't Close
  13.  *      these files yourself, however: they are only lended to you.
  14.  *    . Cleanup of malloc()ed memory on exit.
  15.  *
  16.  *    It supports optionally:
  17.  *    . CLI command line parsing: argc, argv.
  18.  *    . Opening window via the WINDOW tooltypes entry, and closing it on exit.
  19.  *
  20.  *    It DOES support:
  21.  *    . CloseLibrary on DOSBase, MathBase, MathTransBase, MathIeeeDoubBasBase,
  22.  *      if non-NULL.
  23.  *
  24.  *    You can link extra cleanup modules before the rest of exit(), by
  25.  *    setting _cln to your routine, and saving the previous value of _cln.
  26.  *    If it is non-NULL, call it after you have done your extra cleanup.
  27.  *  This pointer is normally used (and ruthlessly overwritten) by malloc().
  28.  */
  29.  
  30. #include <functions.h>
  31.  
  32. #include <exec/alerts.h>
  33. #include <exec/memory.h>
  34. #include <libraries/dosextens.h>
  35. /* #include <workbench/icon.h> */
  36. #include <workbench/workbench.h>
  37. #include <workbench/startup.h>
  38.  
  39.  
  40. void *SysBase, *DOSBase;
  41. void  *MathBase, *MathTransBase, *MathIeeeDoubBasBase;
  42. void *IconBase;
  43.  
  44. long _savsp, _stkbase;    /* Initial SP, and stack base */
  45.  
  46. long   _argcli;        /* Pointer to CLI structure, or NULL (wb) */
  47. char **_argv;        /* Standard C argv (when parsed) */
  48.                     /* or (char *)initial-A0 (when not parsed) */
  49.                     /* or copy of WBenchMsg (when WorkBench) */
  50. int    _argc;        /* Number of arguments (when parsed) */
  51.                     /* or -1 (when not parsed) */
  52.                     /* or 0  (when WorkBench) */
  53. int    _arg_len;    /* Length of reconstructed command line (when parsed) */
  54.                     /* or length of argument part only (D0) (when not parsed) */
  55.                     /* or 0 (when WorkBench) */
  56.  
  57. struct WBStartup *WBenchMsg;    /* Our Workbench startup message */
  58.  
  59.  
  60. #ifdef WB_OPEN_NIL
  61. static char nilname[] = "NIL:";
  62. #else
  63. # ifdef WB_PARSE
  64. static char nilname[] = "NIL:";
  65. # endif
  66. #endif
  67.  
  68. /*
  69.  *    This routine is called from the _main() routine and is used to
  70.  *    open a window for standard I/O to use. The window is actually
  71.  *    defined by setting the ToolType, "WINDOW", to the desired window
  72.  *    specification. If this is not required, this routine may be
  73.  *    replaced by a stub in the users main program. Note that even if
  74.  *    this code is called by _main(), if the WINDOW tool type is not
  75.  *    defined, there will be no window.
  76.  *
  77.  *    EXAMPLE:    WINDOW=CON:0/0/640/200/Test Window
  78.  */
  79.  
  80.  
  81. #ifdef WB_PARSE
  82.  
  83. _wb_parse(pp, wbm)
  84. register struct Process *pp;
  85. struct WBStartup *wbm;
  86. {
  87.     register char *cp;
  88.     register struct DiskObject *dop;
  89.     register struct FileHandle *fhp;
  90.     register long wind;
  91.     void *_OpenLibrary();
  92.     long _Open();
  93.  
  94.     if ((IconBase = _OpenLibrary("icon.library", 0L)) == 0)
  95.         return;
  96.     if ((dop = GetDiskObject(wbm->sm_ArgList->wa_Name)) == 0)
  97.         goto closeit;
  98.     if ( (cp = FindToolType(dop->do_ToolTypes, "WINDOW")) && 
  99.         (wind = _Open(cp, MODE_OLDFILE)) )
  100.     {
  101.         fhp = (struct FileHandle *) (wind << 2);
  102.         pp->pr_ConsoleTask = (APTR) fhp->fh_Type;
  103.         pp->pr_CIS = (BPTR) wind;
  104.         pp->pr_COS = (BPTR) _Open("*", MODE_OLDFILE);
  105.     } else {
  106.         pp->pr_CIS = (BPTR)  _Open(nilname, MODE_OLDFILE);
  107.         pp->pr_COS = (BPTR)  _Open(nilname, MODE_OLDFILE);
  108.     }
  109.     FreeDiskObject(dop);
  110. closeit:
  111.     CloseLibrary(IconBase);
  112.     IconBase = 0;
  113. }
  114.  
  115. #endif /* WB_PARSE */
  116.  
  117.  
  118. #ifdef CLI_PARSE
  119.  
  120. /*
  121.  *    This routine is called from the _main() routine and is used to
  122.  *    parse the arguments passed from the CLI to the program. It sets
  123.  *    up an array of pointers to arguments in the global variables and
  124.  *    and sets up _argc and _argv which will be passed by _main() to
  125.  *    the main() procedure. If no arguments are ever going to be
  126.  *    parsed, this routine may be replaced by a stub routine to reduce
  127.  *    program size.
  128.  *
  129.  *    If _arg_lin is non-zero, the _exit() routine will call FreeMem()
  130.  *    with _arg_lin as the memory to free and _arg_len as the size.
  131.  *
  132.  */
  133.  
  134. char *_arg_lin;
  135.  
  136. _cli_parse(pp, alen, aptr)
  137. struct Process *pp;
  138. long alen;
  139. register char *aptr;
  140. {
  141.     register char *cp;
  142.     register struct CommandLineInterface *cli;
  143.     register int c;
  144.     void *_AllocMem();
  145.  
  146.     cli = (struct CommandLineInterface *)_argcli;
  147.     cp = (char *)((long)cli->cli_CommandName << 2);
  148.     _arg_len = cp[0]+alen+2;
  149.     if ((_arg_lin = _AllocMem((long)_arg_len, 0L)) == 0)
  150.         return;
  151.     strncpy(_arg_lin, cp+1, cp[0]);
  152.     strcpy(_arg_lin+cp[0], " ");
  153.     strncat(_arg_lin, aptr, (int)alen);
  154.     for (_argc = 0, aptr = cp = _arg_lin; ;_argc++) {
  155.         while ((c=*cp) == ' ' || c == '\t' || c == '\f' ||
  156.                 c == '\r' || c == '\n') /* Skip white space */
  157.             cp++;
  158.         if (*cp < ' ')
  159.             break;                    /* End of line */
  160.         if (*cp == '"') {
  161.             cp++;                    /* Quoted argument */
  162.             while (c = *cp++) {        /* Until end of line */
  163.                 *aptr++ = c;
  164.                 if (c == '"') {        /* Another quote */
  165.                     if (*cp == '"') { /* "" is an imbedded quote */
  166.                         cp++;
  167.                     } else {
  168.                         aptr[-1] = 0; /* End of quoted argument */
  169.                         break;
  170.                     }    /* end looking at next char */
  171.                 }    /* end if second quote */
  172.             }    /* end while */
  173.         }    /* end if first quote */
  174.         else {    /* not a quote */
  175.             while ((c=*cp++) && c != ' ' && c != '\t' && c != '\f' &&
  176.                     c != '\r' && c != '\n')    /* Skip until next white space */
  177.                 *aptr++ = c;
  178.             *aptr++ = 0;            /* Null-terminate a word */
  179.         }
  180.         if (c == 0)                    /* At end of line */
  181.             --cp;                    /* backup to the null byte */
  182.     }
  183.     *aptr = 0;
  184.     if ((_argv = _AllocMem((long)(_argc+1)*sizeof(*_argv), 0L)) == 0) {
  185.         _argc = 0;
  186.         return;
  187.     }
  188.     for (c=0, cp=_arg_lin; c < _argc; c++) {
  189.         _argv[c] = cp;                /* Build array of pointers to arguments */
  190.         cp += strlen(cp) + 1;
  191.     }
  192.     _argv[c] = 0;                    /* Null-terminate it */
  193. }
  194.  
  195. #endif /* CLI_PARSE */
  196.  
  197. /*
  198.  *    This is common startup code for both the CLI and the WorkBench,
  199.  *  parsed or not.
  200.  */
  201.  
  202. _main(alen, aptr)
  203. long alen;
  204. char *aptr;
  205. {
  206.     register struct Process *pp, *_FindTask();
  207.     void *_OpenLibrary(), *_GetMsg(), *_AllocMem();
  208.     long _Input(), _Output(), _Open();
  209.  
  210.     _stkbase = _savsp - *((long *)_savsp+1) + 8;
  211.  
  212.     pp = _FindTask(0L);
  213.     
  214.     if (_argcli = pp->pr_CLI << 2) {
  215. #ifdef CLI_PARSE
  216.         _cli_parse(pp, alen, aptr);
  217. #else
  218.         _argv = (char **)aptr;
  219.         _arg_len = alen;    /* Will not be deallocated since not CLI_PARSE */
  220.         _argc = -1;            /* Who would use this ?? */
  221.         aptr[alen - 1] = '\0';    /* Null-termination is easy */
  222. #endif /* CLI_PARSE */
  223.     } else {
  224.         _WaitPort(&pp->pr_MsgPort);
  225.         WBenchMsg = _GetMsg(&pp->pr_MsgPort);
  226.         if (WBenchMsg->sm_ArgList)
  227.             _CurrentDir(WBenchMsg->sm_ArgList->wa_Lock);
  228. #ifdef WB_PARSE
  229.         _wb_parse(pp, WBenchMsg);    /* May open window */
  230. #else
  231. # ifdef WB_OPEN_NIL
  232.         pp->pr_CIS = (BPTR) _Open(nilname, MODE_OLDFILE);
  233.         pp->pr_COS = (BPTR) _Open(nilname, MODE_OLDFILE);
  234. # endif
  235. #endif
  236.         _argv = (char **)WBenchMsg;
  237.         _arg_len = 0;
  238.     }
  239.  
  240.     main(_argc, _argv, _argcli);    /* _argcli is sort of environment... */
  241.  
  242.     exit(0);                        /* This IS necessary! */
  243. }
  244.  
  245.  
  246.  
  247. void (*_cln)();
  248.  
  249. exit(code)
  250. {
  251.     long ret = code;
  252.     register struct Process *pp, *_FindTask();
  253.  
  254.     if (_cln)
  255.         (*_cln)();
  256.  
  257.     if (MathTransBase)
  258.         _CloseLibrary(MathTransBase);
  259.     if (MathBase)
  260.         _CloseLibrary(MathBase);
  261.     if (MathIeeeDoubBasBase)
  262.         _CloseLibrary(MathIeeeDoubBasBase);
  263.     {
  264. #asm
  265.     mc68881
  266.     move.l    4,a6                ;get ExecBase
  267.     btst.b    #4,$129(a6)            ;check for 68881 flag in AttnFlags
  268.     beq        1$                    ;skip if not
  269.     move.l    a5,-(sp)
  270.     lea        2$,a5
  271.     jsr        -30(a6)                ;do it in supervisor mode
  272.     move.l    (sp)+,a5
  273.     bra        1$
  274. 2$
  275.     clr.l    -(sp)
  276.     frestore (sp)+                ;reset the ffp stuff
  277.     rte                            ;and return
  278. 1$
  279. #endasm
  280.     }
  281.     if (WBenchMsg == 0) {
  282. #ifdef CLI_PARSE
  283.         if (_arg_len) {
  284.             _FreeMem(_arg_lin, (long)_arg_len);
  285.             _FreeMem(_argv, (long)(_argc+1)*sizeof(*_argv));
  286.         }
  287. #endif
  288.     } else {
  289. #ifdef WB_CLOSE_FILES
  290.         pp = _FindTask(0L);
  291.         Close(pp->pr_CIS);    /* Close window opened by startup code */
  292.         Close(pp->pr_CIS);    /* or maybe just NIL: files */
  293. #endif
  294.         _Forbid();
  295.         _ReplyMsg(WBenchMsg);
  296.     }
  297.     if (DOSBase)
  298.         _CloseLibrary(DOSBase);
  299.     {
  300. #asm
  301.         move.l    -4(a5),d0        ;pick up return exit code
  302.         move.l    __savsp#,sp        ;get back original stack pointer
  303.         rts                        ;and exit
  304. #endasm
  305.     }
  306. }
  307.  
  308.